package com.fzj.charging.order.config;

import com.fzj.charging.order.mqtt.MqttConsumer;
import com.fzj.charging.order.mqtt.MqttContext;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/**
 * 消息中间件的连接配置
 */
@Configuration//Spring 容器会将这个类视为一个配置类，并且会在启动时自动扫描和处理这个类中的配置信息。
@Slf4j
public class MqttConfiguration {
    @Autowired
    private MqttContext mqttContext;
    /**
     * 连接地址 tcp协议 端口1883
     */
    private final String host = "tcp://127.0.0.1:1883";
    /**
      用户名
     *  */
    private final String userName = "admin";
    /**
     * 密码
     */
    private final String password = "fzj020819";
    /**
     * 客户端id
     * 相同id的客户端不允许同时连接emqx，因此增加了随机数
     */
    private final String clientId = "order_service_client"+Math.random();

    /**
     * Bean注解，创建MqttClient实例交给spring管理，方便后期注入并使用
     * @return
     * @throws MqttException
     */
    @Bean
    public MqttClient mqttClient() throws MqttException {
        //通过连接地址、客户端id进行连接
        MqttClient mqttClient = new MqttClient(host, clientId);
        //连接相关配置
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        //用户名
        mqttConnectOptions.setUserName(userName);
        //密码 需要char[]
        mqttConnectOptions.setPassword(password.toCharArray());
        //清理会话
        mqttConnectOptions.setCleanSession(true);
        //开启自动重连
        mqttConnectOptions.setAutomaticReconnect(true);
        //设置版本号
        mqttConnectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
        //如果你使用new关键字创建了一个对象，那么这个对象就不会被Spring容器所知道或管理。
        // 这意味着这个对象不会享受到Spring提供的任何服务，也不会被Spring的生命周期管理策略所影响。
        // 例如，你无法通过Spring的依赖注入机制向这个对象注入其他bean，也无法让这个对象参与Spring的事务管理。
        MqttConsumer mqttConsumer = new MqttConsumer(mqttClient,mqttContext);
        // 设置回调后，mqttConsumer 实例中的相应方法就会在对应的事件发生时被调用。
        mqttClient.setCallback(mqttConsumer);

        //通过连接配置和EMQX进行连接
        mqttClient.connect(mqttConnectOptions);
        log.debug("准备与emqx建立连接.........");
        return mqttClient;
    }
}
